<?php
/**
 * @link https://www.kancloud.cn/cleverstone/ymb2
 * @copyright Copyright (c) 2020 Yii Manager Software LLC
 */

namespace builder\form\util\control\dselect;

use Yii;
use builder\helper\Url;
use builder\base\UndefinedParamsException;
use builder\form\util\control\Control;
use builder\form\util\control\dselect\options\DsType;
use builder\form\util\control\dselect\options\Modal;
use builder\form\util\control\dselect\options\Page;
use yii\base\InvalidArgumentException;

/**
 * 动态select下拉控件
 * description:
 * 如需支持下拉联动、下拉选项树，请查看`XselectCascader`和`XselectTree`
 *
 * @author cleverstone
 * @since ym2.0
 */
class SelectDynamic extends Control
{
    /**
     * @var array
     */
    private $_options = [
        'control' => 'dynamic_select',
        'label' => '',
        'required' => false,
        'class' => '',
        'style' => '',
        'attribute' => '',
        'comment' => '',
        'help' => '',
        'layout' => 12,
        /** xm-select配置项 */
        'pluginOptions' => [
            'data' => [],
            'initValue' => null,
            'tips' => '请选择',
            'filterable' => false,//是否开启搜索
            'searchTips' => '请选择',//搜索提示
            'delay' => 100,//搜索延迟
            'radio' => false,//是否单选，插件默认多选
            'repeat' => false,//是否开启重复性模式
            'clickClose' => false,//是否点击选项后自动关闭下拉框
            'autoRow' => false,//是否自动换行
            'size' => 'small',//尺寸
        ],
        /** 动态下拉核心配置项 */
        'optionUrl' => '',
        'refreshBtn' => false,
        'additionBtn' => [],
        'btnPosition' => [],
    ];

    /**
     * 控件标签
     * @param string|null $label
     * @return $this
     */
    public function label($label)
    {
        $this->_options['label'] = $label;
        return $this;
    }

    /**
     * 是否必填
     * @param bool $required
     * @return $this
     */
    public function required($required = true)
    {
        $this->_options['required'] = (boolean)$required;
        return $this;
    }

    /**
     * UI
     * @param array|string $class
     * @return $this
     */
    public function uiClass($class)
    {
        $this->formatUiClass($class);
        $this->_options['class'] = $class;

        return $this;
    }

    /**
     * CSS样式
     * @param array|string $style
     * @return $this
     */
    public function style($style)
    {
        $this->formatStyle($style);
        $this->_options['style'] = $style;

        return $this;
    }

    /**
     * HTML属性
     * @param array|string $attribute
     * @return $this
     */
    public function attribute($attribute)
    {
        $this->formatHtmlAttribute($attribute);
        $this->_options['attribute'] = $attribute;

        return $this;
    }

    /**
     * 字段注释
     * @param string $comment
     * @return $this
     */
    public function comment($comment)
    {
        $this->_options['comment'] = (string)$comment;
        return $this;
    }

    /**
     * 帮助文字
     * @param string $help
     * @return $this
     */
    public function help($help)
    {
        $this->_options['help'] = (string)$help;
        return $this;
    }

    /**
     * 布局，1-12
     * @param int $layout
     * @return $this
     */
    public function layout($layout)
    {
        $this->_options['layout'] = (int)$layout;
        return $this;
    }

    /**
     * 下拉选项链接
     * @param array|string $route
     * @return $this
     */
    public function optionUrl($route)
    {
        $this->_options['optionUrl'] = Url::to($route, '');
        return $this;
    }


    /**
     * 新增按钮位置
     * @param string $position
     * @return $this
     */
    public function additionBtnPosition($position = 'left')
    {
        $this->_options['btnPosition']['additionBtn'] = (string)$position;
        return $this;
    }

    /**
     * 刷新按钮位置
     * @param string $position
     * @return $this
     */
    public function refreshBtnPosition($position = 'right')
    {
        if (!empty($this->_options['btnPosition']['refreshBtn'])) {
            $this->_options['btnPosition']['refreshBtn'] = (string)$position;
        }

        return $this;
    }

    /**
     * 动态新增按钮
     * @param array|\Closure|DsType $options
     * @see Modal
     * @see Page
     * @throws UndefinedParamsException
     * @throws \ReflectionException
     * @return $this
     */
    public function additionBtn($options)
    {
        if (is_callable($options)) {
            $options = call_user_func($options);
        }

        if ($options instanceof DsType) {
            $options = $options->_toArray();
        }

        if (!is_array($options)) {
            throw new InvalidArgumentException('Expected parameter [options] is array, But the others are given. ');
        }

        $this->_options['additionBtn'] = $options;
        $this->_options['btnPosition']['additionBtn'] = 'right';

        return $this;
    }

    /**
     * 刷新按钮
     * @return $this
     */
    public function refreshBtn()
    {
        $this->_options['refreshBtn'] = true;
        $this->_options['btnPosition']['refreshBtn'] = 'left';

        return $this;
    }

    /**
     * 是否开启分页
     * @param boolean $paging
     * @return $this
     */
    public function paging($paging)
    {
        $this->_options['pluginOptions']['paging'] = (boolean)$paging;
        return $this;
    }

    /**
     * 工具项
     * ```example
     * //显示工具栏基本配置，包含【全选】【清除】功能。
     * $item->toolbar([
     *     'show' => true,
     * ]);
     * ```
     * @param array $toolbar
     * @return $this
     */
    public function toolbar(array $toolbar)
    {
        $this->_options['pluginOptions']['toolbar'] = $toolbar;
        return $this;
    }

    /**
     * 搜索延迟
     * @param int $millisecond 毫秒
     * @return $this
     */
    public function delay($millisecond)
    {
        $this->_options['pluginOptions']['delay'] = (int)$millisecond;
        return $this;
    }

    /**
     * 设置数据选项
     *
     * 参数           说明                   类型    可选值       默认值
     * name        显示名称                 string    -          name
     * value       选中值, 当前多选唯一      string    -          value
     * selected    是否选中                 string    -         selected
     * disabled    是否禁用                 string    -         disabled
     * children    分组children             string    -         children
     * optgroup    分组optgroup            string     -         optgroup
     *
     * @param array $data
     * @return $this
     */
    public function data(array $data)
    {
        $this->_options['pluginOptions']['data'] = $data;
        return $this;
    }

    /**
     * 默认值
     * @param string|array $defaultValue
     * @return $this
     */
    public function defaultValue($defaultValue)
    {
        $this->_options['pluginOptions']['initValue'] = (array)$defaultValue;
        return $this;
    }

    /**
     * 占位提示
     * @param string $tips
     * @return $this
     */
    public function tips($tips)
    {
        $this->_options['pluginOptions']['tips'] = (string)$tips;
        return $this;
    }

    /**
     * 开启搜索
     * @return $this
     */
    public function filterable()
    {
        $this->_options['pluginOptions']['filterable'] = true;
        return $this;
    }

    /**
     * 搜索提示
     * @param string $tips
     * @return $this
     */
    public function searchTips($tips)
    {
        $this->_options['pluginOptions']['searchTips'] = (string)$tips;
        return $this;
    }

    /**
     * 单选
     * @return $this
     */
    public function radio()
    {
        $this->_options['pluginOptions']['radio'] = true;
        return $this;
    }

    /**
     * 开启重复选
     * @return $this
     */
    public function repeat()
    {
        $this->_options['pluginOptions']['repeat'] = true;
        return $this;
    }

    /**
     * 点击后，自动关闭下拉内容框
     * @return $this
     */
    public function clickClose()
    {
        $this->_options['pluginOptions']['clickClose'] = true;
        return $this;
    }

    /**
     * 自定义属性
     * @param array $options
     *
     * ```example
     *
     * - name: 'label', //data中默认属性[name]映射为[label]
     * - value: 'id',   //data中默认属性[value]映射为[id]
     * ```
     *
     * @return $this
     */
    public function prop(array $options)
    {
        $this->_options['pluginOptions']['prop'] = $options;
        return $this;
    }

    /**
     * 自动换行
     * @return $this
     */
    public function autoRow()
    {
        $this->_options['pluginOptions']['autoRow'] = true;
        return $this;
    }

    /**
     * 新增配置项
     * ```example
     * //把`name`直接作为文本渲染，如果是html不会进行转义。
     * $item->addPluginOption('model', [
     *   'label' => [
     *      'type' => 'text',
     *      'text' => [
     *          'separator' => '，',
     *      ],
     *   ],
     * ]);
     * ```
     * @param string $field
     * @param mixed $value
     * @return $this
     */
    public function addPluginOption($field, $value)
    {
        $this->_options['pluginOptions'][$field] = $value;
        return $this;
    }

    /**
     * @return array
     */
    public function _toArray()
    {
        $options = $this->_options;

        $tmp = ['left' => [], 'right' => []];
        foreach ($options['btnPosition'] as $key => $position) {
            if (!strcasecmp($position, 'left')) {
                $tmp['left'][] = $key;
            } else {
                $tmp['right'][] = $key;
            }
        }
        $options['btnPosition'] = $tmp;

        $viewParams = \Yii::$app->view->params;
        if (
            !isset($options['pluginOptions']['theme'])
            && !empty($viewParams['themeColor'])
        ) {
            $options['pluginOptions']['theme'] = [
                'color' => $viewParams['themeColor']
            ];
        }

        return $options;
    }
}